/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package DatagramPlusPlus;

/**
 *
 * @author rafael
 */
public class WaitTimeOut implements Runnable {
    private long timeOut;
    private long serial;
    private DatagramPlusPlusSocket mainSocket;
    private DatagramReceiver receiver;

    public WaitTimeOut(DatagramPlusPlusSocket mainSocket,DatagramReceiver receiver,long serial,long timeout)    {
        this.mainSocket = mainSocket;
        this.serial = serial;
        this.receiver = receiver;
        timeOut = timeout;
    }

    public void run() {
        try {
            wait(timeOut);
            synchronized(mainSocket.waitingAck) {
                if (mainSocket.waitingAck.get(serial) != null) {
                    // Guarda antigos dados
                    double lastMedia = receiver.mediaRTT;
                    int lastWindow = mainSocket.windowSize;

                    // calculas novos parametros RTT
                    receiver.mediaRTT = (1-receiver.alfa)*receiver.mediaRTT+(double)(receiver.alfa*2*((double)timeOut));
                    mainSocket.timeOut = (long)(receiver.mediaRTT + 4*receiver.desvRTT);

                    if(receiver.mediaRTT+2*receiver.desvRTT >= lastMedia)
//                            || receiver.mediaRTT-2*receiver.desvRTT <= lastMedia)
                        synchronized(mainSocket.windowSize) {
                            mainSocket.windowSize=(int)(0.8*mainSocket.windowSize);
                        }

                    System.out.println("TIMEOUT no pacote nr "+mainSocket.waitingAck.remove(serial)+".");
                    mainSocket.notifyAll();
                }
            }
        } catch (InterruptedException ex) {
            System.err.println("Nao foi possivel verificar o timeout para o pacote nr "+serial+".");
        }
    }

}
